// Package routes Path: routes 注册路由
package routes

import (
	"github.com/gin-gonic/gin"

	"github.com/runningwater/gohub/app/http/controllers/api/v1/auth"
	"github.com/runningwater/gohub/app/http/middlewares"
	"github.com/runningwater/gohub/pkg/config"

	controllers "github.com/runningwater/gohub/app/http/controllers/api/v1"
)

// RegisterAPIRoutes 注册路由
func RegisterAPIRoutes(r *gin.Engine) {
	// v1 路由组，所有 v1 版本的路由都放在这里
	var v1 *gin.RouterGroup
	if len(config.Get("app.api_domain")) == 0 {
		v1 = r.Group("/api/v1")
	} else {
		v1 = r.Group("/v1")
	}

	// 全局限流中间件：每小时限流。这里是所有 API （根据 IP）请求加起来。
	// 作为参考 Github API 每小时最多 60 个请求（根据 IP）。
	// 测试时，可以调高一点。
	v1.Use(middlewares.LimitIP("200-H"))
	{
		uc := new(controllers.UsersController)

		authGroup := v1.Group("/auth")
		{
			suc := new(auth.SignupController)
			vcc := new(auth.VerifyCodeController)
			// 注册手机号是否已存在
			authGroup.POST("/signup/phone/exist", middlewares.GuestJWT(), middlewares.LimitIP("60-H"), suc.IsPhoneExist)
			// 注册邮箱是否已存在
			authGroup.POST("/signup/email/exist", middlewares.GuestJWT(), middlewares.LimitIP("60-H"), suc.IsEmailExist)
			// 注册用户
			authGroup.POST("/signup/using-phone", suc.SignupUsingPhone)
			authGroup.POST("/signup/using-email", suc.SignupUsingEmail)
			// 显示图片验证码
			authGroup.POST("/verify_code/captcha", middlewares.LimitIP("50-H"), vcc.ShowCaptcha)
			// 发送手机验证码
			authGroup.POST("/verify_code/phone", middlewares.LimitIP("20-H"), vcc.SendUsingPhone)
			// 发送邮箱验证码
			authGroup.POST("/verify_code/email", middlewares.LimitIP("20-H"), vcc.SendUsingEmail)

			logc := new(auth.LoginController)
			// 手机号登录
			authGroup.POST("/login/using-phone", logc.LoginByPhone)
			// 账号登录，支持手机号，email 和用户名登录
			authGroup.POST("/login/using-password", logc.LoginByPassword)
			// 刷新 Access Token
			authGroup.POST("/login/refresh-token", logc.RefreshToken)

			// 重置密码
			pc := new(auth.PasswordController)
			// 使用手机重置密码
			authGroup.POST("/password-reset/using-phone", middlewares.LimitPerRoute("20-H"), pc.ResetByPhone)
			// 当前登录用户信息
			authGroup.GET("/user", middlewares.AuthJWT(), uc.CurrentUser)
		}
		userGroup := v1.Group("/users")
		{
			userGroup.GET("", uc.Index)
			userGroup.PUT("", middlewares.AuthJWT(), uc.UpdateProfile)
			userGroup.POST("/email", middlewares.AuthJWT(), uc.UpdateEmail)
			userGroup.POST("/avatar", middlewares.AuthJWT(), uc.UpdateAvatar)
		}
		cgc := new(controllers.CategoriesController)
		categoryGroup := v1.Group("/categories")
		{
			categoryGroup.GET("", cgc.Index)
			categoryGroup.POST("", middlewares.AuthJWT(), cgc.Save)
			categoryGroup.PUT("/:id", middlewares.AuthJWT(), cgc.Update)
			categoryGroup.DELETE("/:id", middlewares.AuthJWT(), cgc.Delete)
		}
		tpc := new(controllers.TopicsController)
		tpcGroup := v1.Group("/topics")
		{
			tpcGroup.GET("", tpc.Index)
			tpcGroup.POST("", middlewares.AuthJWT(), tpc.Store)
			tpcGroup.PUT("/:id", middlewares.AuthJWT(), tpc.Update)
			tpcGroup.DELETE("/:id", middlewares.AuthJWT(), tpc.Delete)
			tpcGroup.GET("/:id", tpc.Show)
		}
		lsc := new(controllers.LinksController)
		linksGroup := v1.Group("/links")
		{
			linksGroup.GET("", lsc.Index)
		}
	}
}
